#include "DAO.h"
#include "User.h"
#include "PublicUtils.h"
#include "Global.h"


void findUserByIdDAO(){

}

void updateUserDAO(){
    
}

/**
 * @brief 通过用户名查找u_id是否存在
 * @author 牢大
*/
int findUserIdByNameDAO(MYSQL *conn, char *uname){
    const char *sql = "SELECT u_id FROM users WHERE u_name = ?";

    MYSQL_STMT *stmt = mysql_stmt_init(conn);


    mysql_stmt_prepare(stmt, sql, strlen(sql));

    // 绑定参数
    MYSQL_BIND bind[1];
    memset(bind, 0, sizeof(bind));

    bind[0].buffer_type = MYSQL_TYPE_STRING;
    bind[0].buffer = (char *)uname;
    bind[0].buffer_length = strlen(uname);

    mysql_stmt_bind_param(stmt, bind);

    // 执行预处理语句
    mysql_stmt_execute(stmt);

    // 绑定结果
    int u_id = 0;
    MYSQL_BIND result[1];
    memset(result, 0, sizeof(result));

    result[0].buffer_type = MYSQL_TYPE_LONG;
    result[0].buffer = (char *)&u_id;
    result[0].buffer_length = sizeof(u_id);

    mysql_stmt_bind_result(stmt, result);

    // 获取结果
    mysql_stmt_store_result(stmt);

    
    mysql_stmt_fetch(stmt);
    // 释放资源
    mysql_stmt_close(stmt);

    return u_id;
    return 0;
}




/**
 * @brief 通过用户名查找user
 * @author 牢大
*/
User* findUserByNameDAO(MYSQL *conn, char *uname) {
    const char *sql = "SELECT u_id, u_name, salt, crypt_pwd FROM users WHERE u_name = ?";

    MYSQL_STMT *stmt = mysql_stmt_init(conn);
    if (stmt == NULL) {
        fprintf(stderr, "mysql_stmt_init() failed\n");
        return NULL;
    }

    if (mysql_stmt_prepare(stmt, sql, strlen(sql)) != 0) {
        fprintf(stderr, "mysql_stmt_prepare() failed\n");
        mysql_stmt_close(stmt);
        return NULL;
    }

    // 绑定参数
    MYSQL_BIND bind[1];
    memset(bind, 0, sizeof(bind));

    bind[0].buffer_type = MYSQL_TYPE_STRING;
    bind[0].buffer = (char *)uname;
    bind[0].buffer_length = strlen(uname);
    bind[0].is_null = 0;
    bind[0].length = 0;

    if (mysql_stmt_bind_param(stmt, bind) != 0) {
        fprintf(stderr, "mysql_stmt_bind_param() failed\n");
        mysql_stmt_close(stmt);
        return NULL;
    }

    if (mysql_stmt_execute(stmt) != 0) {
        fprintf(stderr, "mysql_stmt_execute() failed\n");
        mysql_stmt_close(stmt);
        return NULL;
    }

    // 绑定结果
    MYSQL_RES *result = mysql_stmt_result_metadata(stmt);
    if (result == NULL) {
        fprintf(stderr, "mysql_stmt_result_metadata() failed\n");
        mysql_stmt_close(stmt);
        return NULL;
    }

    MYSQL_BIND result_bind[4];
    memset(result_bind, 0, sizeof(result_bind));

    int uid;
    char uname_out[31];
    char salt[31];
    char crypt_pwd[151];

    unsigned long length[5];
    bool is_null[5];
    bool error[5];

    result_bind[0].buffer_type = MYSQL_TYPE_LONG;
    result_bind[0].buffer = (char *)&uid;
    result_bind[0].is_null = &is_null[0];
    result_bind[0].length = &length[0];
    result_bind[0].error = &error[0];

    result_bind[1].buffer_type = MYSQL_TYPE_STRING;
    result_bind[1].buffer = uname_out;
    result_bind[1].buffer_length = sizeof(uname_out);
    result_bind[1].is_null = &is_null[1];
    result_bind[1].length = &length[1];
    result_bind[1].error = &error[1];

    result_bind[2].buffer_type = MYSQL_TYPE_STRING;
    result_bind[2].buffer = salt;
    result_bind[2].buffer_length = sizeof(salt);
    result_bind[2].is_null = &is_null[2];
    result_bind[2].length = &length[2];
    result_bind[2].error = &error[2];

    result_bind[3].buffer_type = MYSQL_TYPE_STRING;
    result_bind[3].buffer = crypt_pwd;
    result_bind[3].buffer_length = sizeof(crypt_pwd);
    result_bind[3].is_null = &is_null[3];
    result_bind[3].length = &length[3];
    result_bind[3].error = &error[3];



    if (mysql_stmt_bind_result(stmt, result_bind) != 0) {
        fprintf(stderr, "mysql_stmt_bind_result() failed\n");
        mysql_free_result(result);
        mysql_stmt_close(stmt);
        return NULL;
    }

    if (mysql_stmt_store_result(stmt) != 0) {
        fprintf(stderr, "mysql_stmt_store_result() failed\n");
        mysql_free_result(result);
        mysql_stmt_close(stmt);
        return NULL;
    }

    int num_rows = mysql_stmt_num_rows(stmt);
    if (num_rows == 0) {
        mysql_free_result(result);
        mysql_stmt_close(stmt);
        return NULL;
    }

    if (mysql_stmt_fetch(stmt) != 0) {
        fprintf(stderr, "mysql_stmt_fetch() failed\n");
        mysql_free_result(result);
        mysql_stmt_close(stmt);
        return NULL;
    }

    User* user = createUser(uid, uname_out, salt, crypt_pwd, uname_out);

    // 释放资源
    mysql_free_result(result);
    mysql_stmt_close(stmt);
    return user;
}



/**
 * @brief 注册时候插入user表
 * @return 返回插入时的uid
 * @author 牢大
*/
int insertUserDAO(MYSQL *conn, char *uname, char *cryptpwd){
    
    const char *sql = "insert into users (u_name, salt, crypt_pwd) values (?, ?, ?)";
    
    User *user = createUser(0, uname, "", cryptpwd, uname);
    get_salt(user->salt, cryptpwd);

    MYSQL_STMT *stmt = mysql_stmt_init(conn);
    if (stmt == NULL) {
        fprintf(stderr, "mysql_stmt_init() failed\n");
        mysql_error(conn);
    }

    if(mysql_stmt_prepare(stmt, sql, strlen(sql))){
        fprintf(stderr, "mysql_stmt_prepare() failed\n");
        mysql_error(conn);
    }

    // 绑定参数

    MYSQL_BIND bind[3];
    memset(bind, 0, sizeof(bind));


    bind[0].buffer_type = MYSQL_TYPE_STRING;
    bind[0].buffer = (char *)uname;
    bind[0].buffer_length = strlen(uname);

    bind[1].buffer_type = MYSQL_TYPE_STRING;
    bind[1].buffer = (char *)user->salt;
    bind[1].buffer_length = strlen(user->salt);

    bind[2].buffer_type = MYSQL_TYPE_STRING;
    bind[2].buffer = (char *)cryptpwd;
    bind[2].buffer_length = strlen(cryptpwd);


    if(mysql_stmt_bind_param(stmt, bind)){
        fprintf(stderr, "mysql_stmt_bind_param() failed\n");
        mysql_error(conn);
    }

    // 执行预处理语句
    if(mysql_stmt_execute(stmt)){
        fprintf(stderr, "mysql_stmt_execute() failed\n");
        mysql_error(conn);
    }

    int uid = mysql_insert_id(conn);

    // 释放资源
    mysql_stmt_close(stmt);
    destroyUser(user);

    return uid;
}



/**
 * @brief 通过用户id为用户创建根目录
 * @brief 牢大
*/
void insertDirectoryByUserIdDAO(MYSQL *conn, User *user){
    const char *sql = "insert into directories (dir_name, parent_id, u_id, dir_path) values\
                    (?, ?, ?, ?)";

    MYSQL_STMT *stmt = mysql_stmt_init(conn);
    if (stmt == NULL) {
        mysql_error(conn);
    }

    if (mysql_stmt_prepare(stmt, sql, strlen(sql))) {
        mysql_error(conn);
    }

    int parent_id = 0;

    // 绑定参数
    MYSQL_BIND bind[4];
    memset(bind, 0, sizeof(bind));

    bind[0].buffer_type = MYSQL_TYPE_STRING;
    bind[0].buffer = (char *)user->uname;
    bind[0].buffer_length = strlen(user->uname);

    bind[1].buffer_type = MYSQL_TYPE_LONG;
    bind[1].buffer = (char *)&parent_id;
    bind[1].buffer_length = sizeof(parent_id);

    bind[2].buffer_type = MYSQL_TYPE_LONG;
    bind[2].buffer = (char *)&user->uid;
    bind[2].buffer_length = sizeof(user->uid);

    bind[3].buffer_type = MYSQL_TYPE_STRING;
    bind[3].buffer = (char *)user->depository;
    bind[3].buffer_length = strlen(user->depository);

    if (mysql_stmt_bind_param(stmt, bind)) {
        mysql_error(conn);
    }

    // 执行预处理语句
    if (mysql_stmt_execute(stmt)) {
        mysql_error(conn);
    }

    // 释放资源
    mysql_stmt_close(stmt);

}